package org.yoki.edu.image.frame;

import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.highgui.Highgui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.yoki.edu.image.filter.MedianFilter;
import org.yoki.edu.image.utils.MatImageConver;
import sun.awt.geom.AreaOp;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * @author Sky$
 * @Description: TODO
 * @date 2018/2/9$ 11:01$
 */
public class OpenCvFrame extends Frame {

    private static final String TITLE = "彩色图像均值中值滤波3*3";

    private Mat cacheMat, newMat;

    private Image cacheImage, newImage;
    private String fileType;
    private int imageW, imageH;
    private int[] pixels;
    private boolean loadFlag = false;

    /**
     * 面板
     */
    Panel panel;
    /**
     * 装载按钮
     */
    Button btnLoad;
    /**
     * 人脸识别按钮
     */
    Button btnFaceDetector;
    /**
     * 保存按钮
     */
    Button btnSave;
    /**
     * 返回按钮
     */
    Button btnBack;

    public OpenCvFrame() {
        this.setTitle(TITLE);

        panel = new Panel();
        panel.setBackground(Color.lightGray);
        //定义按钮
        btnLoad = new Button("Load");
        btnFaceDetector = new Button("faceDetector");
        btnSave = new Button("Save");
        btnBack = new Button("Back");

        this.add(panel, BorderLayout.SOUTH);
        //添加按钮
        panel.add(btnLoad);
        panel.add(btnFaceDetector);
        panel.add(btnSave);
        panel.add(btnBack);

        //按钮的动作程序  装载图像
        btnLoad.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    loadBtnActionPerformed(e);
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        });

        btnFaceDetector.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                faceDetectorBtnActionPerformed(e);
            }
        });

        //按钮的动作程序  保存
        btnSave.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    saveBtnActionPerformed(e);
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        });
        //按钮的动作程序  退出
        btnBack.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
            }
        });
    }

    /**
     * 加载图像
     *
     * @param e
     * @throws IOException
     */
    public void loadBtnActionPerformed(ActionEvent e) throws IOException {
        File inputFile = chooseFile(this);
        if (null == inputFile) {
            return;
        }
        if (!inputFile.exists()) {
            showWarning("提示：", "装载文件不存在!!!");
        }
        String[] temp = Files.probeContentType(Paths.get(inputFile.getPath())).split("/");
        if (null != temp && temp.length > 1) {
            fileType = temp[1];
        }
        cacheMat = Imgcodecs.imread(inputFile.getPath());
        newMat = cacheMat.clone();
        BufferedImage input = null;
        try {
            input = ImageIO.read(inputFile);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        imageW = input.getWidth();
        imageH = input.getHeight();
        pixels = new int[imageW * imageH];
        cacheImage = input;
        newImage = input;
        loadFlag = true;
        setSize(imageW + 40, imageH + 40 + btnLoad.getHeight());
        repaint();
    }

    public void faceDetectorBtnActionPerformed(ActionEvent e) {
        if (loadFlag) {
            String xmlPath = OpenCvFrame.class.getResource("/haarcascade_frontalface_alt.xml").getPath();
            if (xmlPath.startsWith("/")) {
                xmlPath = xmlPath.substring(1);
            }
            System.out.println("Xml path : " + xmlPath);
            CascadeClassifier faceDetector = new CascadeClassifier(xmlPath);
            MatOfRect faceDetections = new MatOfRect();
            faceDetector.detectMultiScale(cacheMat, faceDetections);
            System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
            for (Rect rect : faceDetections.toArray()) {
                //OpenCV3.30 画图函数Imgproc
                Imgproc.rectangle(newMat,
                        new Point(rect.x, rect.y),
                        new Point(rect.x + rect.width, rect.y + rect.height),
                        new Scalar(0, 255, 0));
                System.out.println("Rect ： " + rect);
            }
            newImage = MatImageConver.conver(newMat);
            repaint();
        } else {
            showWarning("提示：", "请先装载图片!");
        }
    }

    /**
     * 均值滤波
     *
     * @param e
     */

    /**
     * 保存图片
     *
     * @param e
     * @throws IOException
     */
    public void saveBtnActionPerformed(ActionEvent e) throws IOException {
        if (loadFlag) {
            File saveFile = chooseFile(null);
            String temp = Files.probeContentType(Paths.get(saveFile.getPath()));
            if (null == temp || temp.length() <= 0) {
                saveFile = new File(saveFile.getPath() + "." + fileType);
            }
            if (null == saveFile) {
                return;
            }
            if (saveFile.exists()) {
                if (!confirm("确认框", "文件已存在，是否覆盖?")) {
                    return;
                }
                saveFile.deleteOnExit();
            }
            BufferedImage bi = new BufferedImage(newImage.getWidth(null), newImage.getHeight(null),
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = bi.getGraphics();
            g.drawImage(newImage, 0, 0, null);
            g.dispose();

            if (null != fileType && fileType.length() > 0) {
                ImageIO.write(bi, fileType, saveFile);
            } else {
                ImageIO.write(bi, fileType, saveFile);
            }

        } else {
            showWarning("提示：", "请先装载图片!");
        }
    }

    //绘图函数
    @Override
    public void paint(Graphics g) {
        if (loadFlag) {
            g.drawImage(newImage, 20, 20, this);
        } else {
        }
    }


    /**
     * SWT实现的文件夹选择窗口
     *
     * @param parent
     */
    private File chooseFile(Frame parent) {
        JFileChooser jc = new JFileChooser();
        jc.showSaveDialog(parent);
        File file = jc.getSelectedFile();
        return file;
    }

    private boolean confirm() {
        return confirm(null, "确认框", "是否确定?");
    }

    private boolean confirm(String title, String msg) {
        return confirm(null, title, msg);
    }

    private boolean confirm(Frame parent) {
        return confirm(parent, "确认框", "是否确定?");
    }

    private boolean confirm(Frame parent, String title, String msg) {
        int n = JOptionPane.showConfirmDialog(parent, msg, title, JOptionPane.YES_NO_OPTION);
        boolean flag = false;
        if (n == JOptionPane.YES_OPTION) {
            flag = true;
        } else if (n == JOptionPane.NO_OPTION) {
            flag = false;
        }
        return flag;
    }

    /**
     * 显示提示框
     *
     * @param title
     * @param msg
     */
    private void showWarning(String title, String msg) {
        JOptionPane.showMessageDialog(null, msg, title,
                JOptionPane.WARNING_MESSAGE);
    }


}
